【AWS CDK】BucketDeploymentのpruneの設定値はデフォルトでtrueであることに注意しよう
データアナリティクス事業本部のueharaです。
今回は、AWS CDKの aws_s3_deployment.BucketDeployment
のpropsである prune
の設定値はデフォルトでtrueであることに注意しようという内容について説明させて頂きたいと思います。
はじめに
AWS CDKを利用している中で、ローカルファイルのS3へのアップロードに aws_s3_deployment.BucketDeployment
を用いている方は多いのではないでしょうか。
ただ、裏でどのような処理が行われているか知らないままだと思わぬ落とし穴にハマってしまいます。
aws_s3_deploymentについて
公式のドキュメントに記載がありますが、 aws_s3_deployment
モジュールは内部的にはLambda関数を作ってローカルファイルのアップロードを実現しています。
端的に流れを記載すると、以下のようになります。
- ソースのS3バケット(
cdk deploy
コマンドにより資材が配置) → Lambda一時ストレージ - Lambdaの一時ストレージでファイルを展開・処理
- Lambda一時ストレージ → 宛先のS3バケット
ここで、 3.
の実行は aws sync
コマンドで実行されており、冒頭で述べたようにaws_s3_deployment.BucketDeployment
のpropsである prune
のデフォルト値は true
となっているので、 aws sync --delete
で実行されています。
どのような問題が起こるか?
例えば、 resources/dir1
というローカルのディレクトリをS3の cm-da-uehara
バケットに target-path/dir1/
というprefixでアップロードする以下のコードをcdkで書いてみます。
const destinationBucket = s3.Bucket.fromBucketName(this, 'dest-bucket', 'cm-da-uehara');
// S3バケットにファイルをアップロード
new cdk.aws_s3_deployment.BucketDeployment(this, 's3-deploy-dir1', {
sources: [cdk.aws_s3_deployment.Source.asset("resources/dir1")],
destinationBucket: destinationBucket,
destinationKeyPrefix: 'target-path/dir1/',
});
cdk deploy
コマンドによりデプロイが完了すると、以下の通りS3にファイルがアップロードされます。
次に、 同じS3バケットに対し target-path/
というprefixで resources/dir2
のディレクトリファイルをアップロードする処理を追記します。
const destinationBucket = s3.Bucket.fromBucketName(this, `dest-bucket`, 'cm-da-uehara');
// S3バケットにファイルをアップロード
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir1`, {
sources: [cdk.aws_s3_deployment.Source.asset("resources/dir1")],
destinationBucket: destinationBucket,
destinationKeyPrefix: 'target-path/dir1/',
});
// ★新規追加
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
destinationBucket: destinationBucket,
destinationKeyPrefix: 'target-path/',
});
再度 cdk deploy
コマンドでデプロイを行いS3バケットを確認すると、 resources/dir2
の中にあったファイルは target-path/
というprefixでアップロードされていますが、先ほどアップロードした dir1
が削除されています。
これは、先に説明した通りデフォルトでは s3 sync --delete
で実行されているため、 target-path/
というpredfixに対して追記分のファイルのみで sync
されることにより、既に存在した target-path/dir1/
のprefixを持つファイルが削除されてしまうことに起因します。
解決方法
方法1
propsの prune
を false
にすると --delete
オプションが利用されないので、それで対処することができます。
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
destinationBucket: destinationBucket,
destinationKeyPrefix: 'target-path/',
prune: false,
});
方法2
その他単純な対処として、prefixを変えてしまえば(当然ですが)削除はされません。
new cdk.aws_s3_deployment.BucketDeployment(this, `s3-deploy-dir2`, {
sources: [cdk.aws_s3_deployment.Source.asset("resources/dir2")],
destinationBucket: destinationBucket,
destinationKeyPrefix: 'target-path-xxx/',
});
最後に
今回は、AWS CDKの aws_s3_deployment.BucketDeployment
のpropsである prune
の設定値はデフォルトでtrueであることに注意しようという内容について説明させて頂きました
参考になりましたら幸いです。